package com.example.gobang.game;


import com.example.gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 这个类用来  处理匹配
 */
@Component
public class Match {


    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private RoomManger roomManger;

    //3个不同天梯分的匹配队列
    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();

    //玩家在线状态
    @Autowired
    private OnlineUserManager onlineUserManager;

    /**
     * 加入匹配队列
     * @param user
     */
    public void add(User user){
        if (user.getScore() < 2000){
            synchronized (normalQueue){
                normalQueue.add(user);
                normalQueue.notify();
            }
            System.out.println("用户： "+user.getUsername()+"进入normalQueue匹配队列");
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue){
                highQueue.add(user);
                highQueue.notify();
            }
            System.out.println("用户： "+user.getUsername()+"进入highQueue匹配队列");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.add(user);
                veryHighQueue.notify();
            }
            System.out.println("用户： "+user.getUsername()+"进入veryHighQueue匹配队列");
        }
    }

    /**
     * 用户取消匹配
     * @param user
     */
    public void remove(User user){
        if (user.getScore() < 2000){
            synchronized (normalQueue){
                normalQueue.remove(user);
            }
            System.out.println("用户： "+user.getUsername()+"取消normalQueue匹配");
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue){
                highQueue.remove(user);
            }
            System.out.println("用户： "+user.getUsername()+"取消highQueue匹配");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.remove(user);
            }
            System.out.println("用户： "+user.getUsername()+"取消veryHighQueue匹配");
        }
    }

    public Match(){
        new Thread(() -> {
            while(true){
              handleMatch(normalQueue);
            }
        }).start();

        new Thread(() -> {
            while(true){
                handleMatch(highQueue);
            }
        }).start();

        new Thread(() -> {
            while(true){
                handleMatch(veryHighQueue);
            }
        }).start();
    }

    private void handleMatch(Queue<User> matchQueue) {
        synchronized (matchQueue){
            try {
                while (matchQueue.size() < 2){
                    matchQueue.wait();
                }
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配到了两个人玩家： "+player1.getUsername()+" - "+player2.getUsername());
                //判断在线状态
                WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserId());
                if (session1 == null) {
                    // 如果玩家1 下线, 则把玩家2 放回匹配队列
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null) {
                    // 如果玩家2 下线, 则把玩家1 放回匹配队列
                    matchQueue.offer(player1);
                    return;
                }
                if (session1 == session2) {
                    // 如果得到的两个 session 相同, 说明是同一个玩家两次进入匹配队列
                    // 例如玩家点击开始匹配后, 刷新页面, 重新再点开始匹配
                    // 此时也把玩家放回匹配队列
                    matchQueue.offer(player1);
                    return;
                }

                // 3. 将这两个玩家加入到游戏房间中.
                Room room = new Room();
                roomManger.add(room, player1.getUserId(),player2.getUserId());

                // 4. 给玩家1 发回响应数据
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));
                // 5. 给玩家2 发回响应数据
                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));
            }catch (IOException | InterruptedException e){
                e.printStackTrace();
            }
        }

    }

}
